package com.uh.microservice.core.service;

import com.uh.microservice.core.CONSTANTS;
import com.uh.microservice.core.dao.JdbcDao;
import com.uh.microservice.core.enums.YesOrNoEnum;
import com.uh.microservice.core.util.CacheUtil;
import com.uh.microservice.core.util.DateUtil;
import com.uh.microservice.core.spring.bean.CacheAspect;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.concurrent.CountDownLatch;

/**
 * Created by liming on 2017/9/30.
 * 所有的需要数据缓存的方法都写在这个类里面
 * @see CacheAspect
 * 缓存切面，监控使用缓存的数据请求，优先加载缓存
 */

@Component
public class CacheService {
    @Autowired
    private JdbcDao dao;

    @Autowired
    ScriptComponent scriptComponent;

    /**
     * @param sid system online user id,when the user dologin generate.
     * @return Map{SID(SYS_ONLINE_USER ID),ID(USER_ID),ACCOUNT,NAME,LOGIN_USER_DEPT }
     */
    public Map findUInfo(String sid) {
        Map param = new HashMap(1);
        param.put("ONLINE_ID", sid);
        param.put("STATUS", YesOrNoEnum.YES.key);
        Map row = dao.loadRowByCode("pub_online_qry", param);
        //判断时间是否会过期
        if (row != null) {
            Date effectiveDate = (Date) row.get("EFFECTIVE_DATE");
            if (effectiveDate != null && DateUtil.getTwoTimeDiffSecond(new Date(), effectiveDate) > 0) {
                return null;
            }

            param.put("USER_ID", row.get(CONSTANTS.C_PK));
            List<Object> deptId = new ArrayList<>();
            List<Map> depts = dao.loadListByCode("dept_query_dept_id", param);
            depts.forEach(dept -> {
                        deptId.add(dept.get(CONSTANTS.C_PK));
                    }
            );
            row.put(CONSTANTS.REQ_DEPT, deptId);
            //查询用户角色
            List<Map> roleNames = dao.loadListByCode("user_role_query_name", new HashMap() {{
                put("USER_ID", row.get(CONSTANTS.C_PK));
            }});
            if (roleNames != null && roleNames.size() != 0) {
                row.put("ROLE_NAME", new ArrayList() {{
                    roleNames.forEach(name -> {
                        add(name.get("NAME"));
                    });
                }});
                row.put("ROLE_TYPE", new ArrayList() {{
                    roleNames.forEach(name -> {
                        add(name.get("TYPE"));
                    });
                }});
            }

            List<Map> sysParams=dao.loadListByCode("param_query_list",new HashMap(){{
                put("CODELIKE","SYS_MAIN_%");
            }});
            Map paramMap=new HashMap();
            sysParams.forEach(sysp->{
                paramMap.put(sysp.get("CODE"),sysp.get("VALUE"));
            });

            row.put("SYS_PARAM",paramMap);
        }
        return row;
    }

    public Map findSysParams2Map(Map  pmp){
        List<Map> sysParams=dao.loadListByCode("param_query_list",pmp);
        Map paramMap=new HashMap();
        sysParams.forEach(sysp->{
            paramMap.put(sysp.get("CODE"),sysp.get("VALUE"));
        });
        return paramMap;
    }


    /**
     * @param sid system online user id,when the user dologin generate.
     * @return Map{SID(SYS_ONLINE_USER ID),ID(USER_ID),ACCOUNT,NAME,LOGIN_USER_DEPT }
     */
    public Map findAppUInfo(String sid) {
        Map param = new HashMap(1);
        param.put("ONLINE_ID", sid);
        Map row = dao.loadRowByCode("app_cust_get_online_user_by_OnlineId", param);
        return row;
    }

    /**
     * 日志规则查询
     *
     * @return 日志规则记录
     */
    public Map<String, Object> findLogCfg(Map<String, String> param) {
        return dao.loadRowByCode("log_cfg_query", param);
    }

    /**
     * 获取收费员信息
     *
     * @param sid system online user id,when the user dologin generate.
     * @return
     */
    public static String CACHE_COLLECTOR_INFO_NAME = "findCollectorInfo_";
    public Map findCollectorInfo(String sid) {
        Map param = new HashMap(1);
        param.put("ONLINE_ID", sid);
        Map row = dao.loadRowByCode("pub_online_collector_qry", param);
        return row;
    }

    public Map findMsgModle(String contentType,String terminalType) {
        Map param = new HashMap(1) {{
            put("CONTENT_TYPE", contentType);
            put("TERMINAL_TYPE", terminalType);
        }};
        Map row = dao.loadRowByCode("msg_modle_qry_by_content_type", param);
        return row;
    }

    /**
     * 计费获取所需的数据
     * 存入缓存前缀 为 "RATE_CACHE" {@link CacheAspect#addNameSpace(String)}
     *
     * @param code
     * @param prm
     * @return
     */
    public List<Map> findBillRateCollection(String code, Map prm) {
        return dao.loadListByCode(code, prm);
    }

    public List<Map> findCacheByCode(String code,Map prm){
        return dao.loadListByCode(code, prm);
    }

    public Map findCacheRow(String code,Map prm){
        return dao.loadRowByCode(code,prm);
    }

    /**
     * 存入缓存前缀 为 "SYS_PARAM_CACHE" {@link CacheAspect#addNameSpace(String)}
     */
    public String findSysParams(@NotNull String parameterCode) {
        Map paramKey = dao.loadRowByCode("param_query_by_code", new HashMap() {{
            put("CODE", parameterCode);
        }});
        if (paramKey == null || paramKey.isEmpty()) {
            return null;
        } else {
            return (String) paramKey.get("VALUE");
        }
    }

    public Map findRateDesc(String areaType, String parkType, String deptId) {
        Map params = new HashMap() {{
            put("AREA_TYPE", areaType);
            put("PARK_TYPE", parkType);
            put("DEPT_ID", deptId);
        }};
        String crruentTime = DateUtil.format(new Date());
        params.put("BEGIN_TIME", crruentTime);
        params.put("END_TIME", crruentTime);
        try {
        Map resultMap=new HashMap(6);
        CountDownLatch latch = new CountDownLatch(3);
        new Thread(()->{
            List<Map>  rateDesc = (List<Map>) scriptComponent.excute("pub.cmn.bill.query.descripteRate", new HashMap() {{
                put("db", dao);
                put("prm", params);
            }});
            resultMap.put("DESC", rateDesc);
            latch.countDown();
        }).start();
        new Thread(()->{
            List<Map> feeStep = (List<Map>) scriptComponent.excute("pub.cmn.bill.query.queryFeeStep", new HashMap() {{
                put("db", dao);
                put("prm", params);
            }});
            resultMap.put("FEE_STEP", feeStep);
            latch.countDown();
        }).start();
        new Thread(()->{
            List<Map<String, String>> rateList = dao.loadListByCode("query_list_bill_rate", new HashMap() {{
                put("AREA_TYPE", areaType);
                put("PARK_TYPE", parkType);
                put("BEGIN_TIME", new Date());
                put("END_TIME", new Date());
            }});
            String RATE_NOT_FIND_STR = "暂时未录入（以现场收费标准为准）";
            Map appDesc = new HashMap();
            if (rateList.size() == 1) {
                Map rate = rateList.get(0);
                String dayDesc = (String) rate.get("DAY_RATE_DESCRIPTION");
                String nightDesc = (String) rate.get("NIGHT_RATE_DESCRIPTION");
                appDesc.put("DAY_DESC", StringUtils.isEmpty(dayDesc) ? RATE_NOT_FIND_STR : dayDesc);
                appDesc.put("NIGHT_DESC", StringUtils.isEmpty(nightDesc) ? RATE_NOT_FIND_STR : nightDesc);
            }
            resultMap.put("APP_DESC", appDesc);
            latch.countDown();
        }).start();
            latch.await();
            return resultMap;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
       return null;
    }

    public void findPayTypeList() {
        List list = dao.loadListByCode("pay_type_query_list", new HashMap() {});
        CacheUtil.instance().putKey(CacheUtil.CACHE_NAME_SPACE_PAY_TYPE,list);
    }

    public String getPayTypeNameOld(int payTypeCode)
    {
        Map paramKey = dao.loadRowByCode("pay_type_query_by_code", new HashMap() {{
            put("CODE_VALUE", payTypeCode);
        }});
        if (paramKey == null || paramKey.isEmpty()) {
            return null;
        } else {
            return (String) paramKey.get("CODE_NAME");
        }
    }

    // 2018年12月24日16:01:28 dws
    public String getPayTypeName(int payTypeCode) {
        // 尝试从缓存读取对象
        Object cacheObj = CacheUtil.instance().getKey(CacheUtil.CACHE_NAME_SPACE_PAY_TYPE);
        if (cacheObj == null) {
            // 从db重新读取，放入缓存
            findPayTypeList();
        }
        // 重新从缓存读取对象
        cacheObj = CacheUtil.instance().getKey(CacheUtil.CACHE_NAME_SPACE_PAY_TYPE);

        if (cacheObj == null) {
            return null;
        } else {
            if (cacheObj instanceof List) {
                List<Map> list = (List) cacheObj;
                for (Map map : list) {
                    if ((map.get("CODE_VALUE") + "").equals(payTypeCode + "")) {
                        return map.get("CODE_NAME") + "";
                    }
                }
            }
            return null;
        }
    }
}
